package model;

import java.util.ArrayList;
import java.util.List;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databeans.Sid_Respondent;
import databeans.Survey;
import interfas.Sid_RespondentInterface;

public class Sid_RespondentDAO implements Sid_RespondentInterface {

	private BeanFactory<Sid_Respondent> factory;
	
	public Sid_RespondentDAO() throws DAOException {
		try {
			BeanTable<Sid_Respondent> table = BeanTable.getInstance(Sid_Respondent.class, "sid_respondent");
			if (!table.exists())
				table.create("sid", "respid");
			
			table.setIdleConnectionCleanup(true);
			factory = table.getFactory();
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(Sid_Respondent sr, SurveyDAO surveyDAO, UserDAO userDAO) throws DAOException {
		try {
			// Check for foreign key constraint
			if (surveyDAO.lookup(sr.getSid()) == null) {
				throw new DAOException("sid must exist in survey table");
			}
			if (userDAO.lookup(sr.getRespid()) == null) {
				throw new DAOException("respid must exist in user table");
			}
			
			Transaction.begin();
			Sid_Respondent dbSr = factory.create(sr.getSid(), sr.getRespid());
			factory.copyInto(sr, dbSr);
			Transaction.commit();
		} catch (DuplicateKeyException e) {
			throw new DAOException("A sid_respondent with sid " + sr.getSid() + " and respid " + sr.getRespid() + " already exists");
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public Sid_Respondent lookup(int sid, String respid) throws DAOException {
		try {
			return factory.lookup(sid, respid);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public Survey[] getSurveyByResp(String respid, SurveyDAO surveyDAO) throws DAOException {
		try {
			Sid_Respondent[] srlist = factory.match(MatchArg.equals("respid", respid));
			List<Survey> surveylist = new ArrayList<Survey>();
			
			for (int i = 0; i < srlist.length; i++) {
				if (srlist[i].getCompleted() == 0)
					surveylist.add(surveyDAO.lookup(srlist[i].getSid()));
			}
			
			return surveylist.toArray(new Survey[surveylist.size()]);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public int numRespondents(int sid) throws DAOException {
		try {
			Sid_Respondent[] result = factory.match(MatchArg.equals("sid", sid));
			return result.length;
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public int numCompleted(int sid) throws DAOException {
		try {
			Sid_Respondent[] result = factory.match(MatchArg.equals("sid", sid), MatchArg.equals("completed", 1));
			return result.length;
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public void updateCompleted(Sid_Respondent sr) throws DAOException {
		try {
			Transaction.begin();
			Sid_Respondent dbSr = lookup(sr.getSid(), sr.getRespid());
			if (dbSr == null)
				throw new DAOException("Sid_Respondent with sid " + sr.getSid() + " and respid " + sr.getRespid() + " doesn't exist");
			dbSr.setCompleted(sr.getCompleted());
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public void delete(int sid, String respid) throws DAOException {
		try {
			Transaction.begin();
			Sid_Respondent dbsr = lookup(sid, respid);
			if (dbsr == null)
				throw new DAOException("Sid_Respondent with sid " + sid + " and respid " + respid + " doesn't exist");
			factory.delete(sid, respid);
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public int size() throws DAOException {
		try {
			return factory.getBeanCount();
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
}
